from sklearn.svm import LinearSVC
import cv2  #导入opencv模块
import numpy as np
import os
import matplotlib.pyplot as plt
from math import pi
import pickle
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from project_utils import project_tools
from sklearn.svm import LinearSVC
class model_tools():

    @staticmethod
    def save_model(model,model_name):
        save_model_path=project_tools.project_root_path()+'\\'+project_tools.models_dirname+'\\'+model_name+'.pkl'
        try:
            f = open(save_model_path, 'wb')
            pickle.dump(model, f)
            f.close()
            print('虫种识别模型:'+model_name+'.pkl写入成功！')
        except:
            print('虫种识别模型:'+model_name+'.pkl写入失败！')

    @staticmethod
    def save_scaler(scaler,scaler_name):
        save_scaler_path=project_tools.project_root_path()+'\\'+project_tools.models_dirname+'\\'+scaler_name+'_scaler.pkl'
        try:
            f = open(save_scaler_path, 'wb')
            pickle.dump(scaler, f)
            f.close()
            print('数据缩放器:' + scaler_name + '_scaler.pkl写入成功！')
        except:
            print('数据缩放器:' + scaler_name + '_scaler.pkl写入失败！')

    # 融合不同图片上昆虫的特征矩阵,other_insects_chas_path为其他待融合的昆虫特征文件目录和特征行索引范围，以列表格式传入
    @staticmethod
    def merge_insects_chas_from_file(base_insects_chas_paths,index_range):
        base_insects_chas=np.loadtxt(base_insects_chas_paths[0])[index_range[0][0]:index_range[0][1]]
        for insect_chas, range in zip(base_insects_chas_paths[1:],index_range[1:]):
            other_insects_chas=np.loadtxt(insect_chas)[range[0]:range[1]]
            base_insects_chas=np.append(base_insects_chas,other_insects_chas,axis=0)
        return base_insects_chas

    # 融合人工标记的昆虫标签,other_insects_tags_path为其他待融合的昆虫标签文件目录，以列表格式传入
    @staticmethod
    def merge_insects_tags_from_file(base_insects_tag_path, other_insects_tag_paths):
        base_insects_tags = np.array([])
        index_range = []
        insects_chas_paths = []
        for insect_tag in base_insects_tag_path:
            insects_tags = np.loadtxt(insect_tag)
            max_tag_index = insects_tags.shape[0]
            index_range.append((0, max_tag_index))
            base_insects_tags = np.append(base_insects_tags, insects_tags)
        return base_insects_tags


    # 一键自动关联insects_tags和其对应的insects_chas并保证数据纬度一致
    @staticmethod
    def merge_insects_chas_and_tags(insects_tags_paths):
        base_insects_tags=np.array([])
        index_range=[]
        insects_chas_paths=[]
        for insect_tag in insects_tags_paths:
            insects_tags=np.loadtxt(insect_tag)
            max_tag_index=insects_tags.shape[0]#读出文件里面有几个标签
            index_range.append((0,max_tag_index))
            base_insects_tags=np.append(base_insects_tags,insects_tags)
            # 查找tag对应的chas文件路径
            filename = os.path.splitext(insect_tag)[0].rsplit('\\', 1)[1]#取出5-1-1-A
            insects_chas_path=project_tools.project_root_path()+'\\'+project_tools.trainning_source_dirname+'\\'+filename+'.txt'
            insects_chas_paths.append(insects_chas_path)
        base_insects_chas=model_tools.merge_insects_chas_from_file(insects_chas_paths,index_range)

        return base_insects_chas,base_insects_tags

    # 根据给出的模型类型构建该训练模型
    # input:病虫害特征数据，病虫害标签数据，模型类型，保存模型的名称
    # output:训练完成的模型
    @staticmethod
    def construct_model(base_insects_chas,base_insects_tags,model,model_name):
        #save_model_path=project_tools.project_root_path()+'\\'+project_tools.models_dirname+'\\'+model_name+'.pkl'
        X=base_insects_chas
        y=base_insects_tags
        X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
        scaler = MinMaxScaler()
        scaler.fit(X_train)
        X_train_scaler=scaler.transform(X_train)
        X_test_scaler=scaler.transform(X_test)
        model.fit(X_train_scaler, y_train)
        model_tools.save_model(model,model_name)
        model_tools.save_scaler(scaler,model_name)
        print('训练集精度:',model.score(X_train_scaler, y_train))
        print('测试集精度:',model.score(X_test_scaler, y_test))


# X_train_1=np.loadtxt('D:\python\workspace\insects_detection\chas_data\\5-2-1-A.txt')
# X_train_2=np.loadtxt('D:\python\workspace\insects_detection\chas_data\\5-1-4-A.txt')[0:200]
# X_train=np.append(X_train_1,X_train_2,axis=0)
# y_train_1=np.loadtxt('D:\python\workspace\insects_detection\insects_tags\\5-2-1-A.txt')
# y_train_2=np.loadtxt('D:\python\workspace\insects_detection\insects_tags\insects_tags.txt')
# y_train=np.append(y_train_1,y_train_2)
# print(X_train.shape[0])
# print(y_train.shape)
# scaler=MinMaxScaler()
# scaler.fit(X_train)
# X_train_scaler=scaler.transform(X_train)
# X_train_scaler,X_test_scaler,y_train,y_test=train_test_split(X_train_scaler,y_train,random_state=0)
# model=LinearSVC(max_iter=100000,C=150)
# model.fit(X_train_scaler,y_train)
# f = open('D:\python\workspace\insects_detection\\trainning_models\\train_data_1.pkl', 'wb')
# pickle.dump(model, f)
# f.close()
# print(model.score(X_train_scaler,y_train))
# print(model.score(X_test_scaler,y_test))